<?php

namespace app\common\library;


use think\Hook;

/**
 * 短信验证码类
 */
class Sms
{

    /**
     * 验证码有效时长
     * @var int 
     */
    protected static $expire = 120;

    /**
     * 最大允许检测的次数
     * @var int 
     */
    protected static $maxCheckNums = 10;

    /**
     * 获取最后一次手机发送的数据
     *
     * @param   int       $mobile   手机号
     * @param   string    $event    事件
     * @return  Sms
     */
    public static function get($mobile, $event='default')
    {
       $redis = new \Redis();
       $redis->connect('127.0.0.1', 6379);
       $redis->auth('hdyjredis');
       $keyName=$event.'_mobile:'.$mobile;
       if($redData=$redis->hGetAll($keyName)){
            return false;
       }
       return true;
      
    }

    /**
     * 发送验证码
     *
     * @param   int       $mobile   手机号
     * @param   int       $code     验证码,为空时将自动生成4位数字
     * @param   string    $event    事件
     * @return  boolean
     */
    public static function send($mobile, $code = NULL, $event = 'default')
    {

        $code = is_null($code) ? mt_rand(1000, 9999) : $code;
        $time = time();
        $redis = new \Redis();
        $redis->connect('127.0.0.1', 6379);
        $redis->auth('hdyjredis');
        $keyName = $event.'_mobile:'.$mobile;
        $arrIns=['createtime'=>$time,'starttime'=>$time+60*50,'code'=>$code];
        //redis存储
        if($redData=$redis->hGetAll($keyName)){
            if($time > $redData['starttime']){
                $redis->hMset($keyName,$arrIns);
                $redis->expire($keyName,125);
            }else{
                $redis->hMset($keyName,$arrIns);
            }
        }else{
            $redis->hMset($keyName,$arrIns);
            $redis->expire($keyName,125);
        }
        $client = new \SoapClient(config('dcxsms.url'));
        // 参数转为数组形式传递
        $aryPara = array(
            'user'=>config('dcxsms.user'),
            'pwd'=>config('dcxsms.pwd'),
            'mobiles'=>$mobile,
            'contents'=> sprintf(config('dcxsms.template'),$code)
        );
        $response = $client->SendMessage($aryPara);
        $res = Sms::xml_to_array($response->SendMessageResult);
        if($res['result'] != '0')
        {
            $redis->del($keyName);
        }
        return  $res;
    }

    /**
     * 发送通知
     * 
     * @param   mixed     $mobile   手机号,多个以,分隔
     * @param   string    $msg      消息内容
     * @param   string    $template 消息模板
     * @return  boolean
     */
    public static function notice($mobile, $msg = '', $template = NULL)
    {
        $params = [
            'mobile'   => $mobile,
            'msg'      => $msg,
            'template' => $template
        ];
        $result = Hook::listen('sms_notice', $params, null, true);
        return $result ? TRUE : FALSE;
    }

    public static function xml_to_array($xml)
    {
        $array = (array)(simplexml_load_string($xml));
        foreach ($array as $key=>$item){
            $array[$key]  =  Sms::struct_to_array((array)$item);
        }
        return $array;
    }

    public static function struct_to_array($item) {
        if(!is_string($item)) {
            $item = (array)$item;
            foreach ($item as $key=>$val){
                $item  = Sms::struct_to_array($val);
            }
        }
        return $item;
    }
    
    /**
     * 校验验证码
     *
     * @param   int       $mobile     手机号
     * @param   int       $code       验证码
     * @param   string    $event      事件
     * @return  boolean
     */
    public static function check($mobile, $code, $event = 'default')
    {
       $redis = new \Redis();
       $redis->connect('127.0.0.1', 6379);
       $redis->auth('hdyjredis');
       $keyName=$event.'_mobile:'.$mobile;
       if($redData=$redis->hGetAll($keyName)){
            if($redData['code']!= $code){
                return false;
            }
       }else{
            return false;
       }
       return true;
    }

    /**
     * 清空指定手机号验证码
     *
     * @param   int       $mobile     手机号
     * @param   string    $event      事件
     * @return  boolean
     */
    public static function flush($mobile, $event = 'default')
    {
        \app\common\model\Sms::
                where(['mobile' => $mobile, 'event' => $event])
                ->delete();
        Hook::listen('sms_flush');
        return TRUE;
    }

}
